package com.wd.live.view.activity

import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.util.Log
import android.view.SurfaceView
import android.view.View
import android.widget.Adapter
import android.widget.FrameLayout
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.lifecycle.Observer
import com.blankj.utilcode.util.GsonUtils
import com.blankj.utilcode.util.ImageUtils
import com.blankj.utilcode.util.SPUtils
import com.blankj.utilcode.util.ToastUtils
import com.blankj.utilcode.util.UriUtils
import com.google.gson.Gson
import com.wd.live.R
import com.wd.live.databinding.ActivityDialogBinding
import com.wd.live.model.SocketBean
import com.wd.live.model.base.BaseActivity
import com.wd.live.model.bean.LM_QuerylistBean
import com.wd.live.model.bean.LocalData
import com.wd.live.model.tool.BaseConstant
import com.wd.live.tool.socket.WebSocketUtils
import com.wd.live.view.custom.CustomDialog
import com.wd.live.view.custom.CustomDialog_four
import com.wd.live.view.custom.CustomDialog_gift_list
import com.wd.live.view.custom.CustomDialog_three
import com.wd.live.view.custom.callback
import com.wd.live.view.custom.longToast
import com.wd.live.viewmodel.OpenLiveViewModel
import com.wd.live.wxapi.UserInfo
import io.agora.rtc2.ChannelMediaOptions
import io.agora.rtc2.Constants
import io.agora.rtc2.IRtcEngineEventHandler
import io.agora.rtc2.RtcEngine
import io.agora.rtc2.RtcEngineConfig
import io.agora.rtc2.video.VideoCanvas
import java.io.File

//开播：

//1、在同一个appid下面测试，要保持一致
//2、集成：
// 01：申请开播接口，申请开播成功后，返回信息（token，鉴权，直播号），
//           对声网的本地的客户端的SDK进行初始化，初始化两个关键步骤：
//	    通过handler回调方法来通知我们，这个回调方法里有一个加入频道成功
//	    的方法，我们可以在这里面调用服务端的接口进行推流的操作，（我们服
//	    务端会告诉我们声网的服务端，我们整个渠道就打开了，进行推流操作）

/**
 * 作者：马海钊
 * 时间：2023年8月21日09:53:26
 * 功能：开启直播
 */
class DialogActivity : BaseActivity<OpenLiveViewModel, ActivityDialogBinding>() {
    //    var callback:(LM_QuerylistBean)->Unit={}
    var file: File? = null
    var i: Int? = null

    // 填写项目的 App ID，可在声网控制台中生成。
    private val appId = BaseConstant.OPEN_LIVE_ID

    private val PERMISSION_REQ_ID = 22

    //获取权限
    private val REQUESTED_PERMISSIONS = arrayOf(
        Manifest.permission.RECORD_AUDIO,
        Manifest.permission.CAMERA
    )

    private fun checkSelfPermission(permission: String, requestCode: Int): Boolean {
        if (ContextCompat.checkSelfPermission(this, permission) !=
            PackageManager.PERMISSION_GRANTED
        ) {
            ActivityCompat.requestPermissions(this, REQUESTED_PERMISSIONS, requestCode)
            return false
        }
        return true
    }

    private var mRtcEngine: RtcEngine? = null

    //动态权限


    //c6b293bbb6f54e818f06ffca4f8c9c12
    // 填写频道名称。
//    private val channelName = "china"
//
//    //china
//    // 填写声网控制台中生成的临时 Token。
//    private val token =
//        "007eJxTYAiZ/L4ucfEUjTsX+AOWzO59e9j16Png398POt4WXvB0RZWXAkOyWZKRpXFSUpJZmqlJqoWhRZqBWVpacqJJmkWyZbKh0TXhJykNgYwMf9YYMjIyQCCIz8qQnJGZl8jAAACPuiPw"

    //007eJxTYAiZ/L4ucfEUjTsX+AOWzO59e9j16Png398POt4WXvB0RZWXAkOyWZKRpXFSUpJZmqlJqoWhRZqBWVpacqJJmkWyZbKh0TXhJykNgYwMf9YYMjIyQCCIz8qQnJGZl8jAAACPuiPw


    //    override fun onResume() {
//        super.onResume()
//        // 如果已经授权，则初始化 RtcEngine 并加入频道。
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//            requestPermissions(
//                arrayOf(
//                    Manifest.permission.READ_EXTERNAL_STORAGE,//读取外部存储
//                    Manifest.permission.WRITE_EXTERNAL_STORAGE//写入外部存储
//                    , Manifest.permission.RECORD_AUDIO//录制音频
//                    , Manifest.permission.CAMERA//相机
//                ), 1000);
//        }
//    }
    //	    设置一个mEventHandler的事件回调对象，这个事件会与我们声网的
//                 SDK交互，根据这个事件会返回一些关键的信息，所以要根据这个Handler
//                 做一下初始化设置
    private val mRtcEventHandler: IRtcEngineEventHandler = object : IRtcEngineEventHandler() {
        // 监听频道内的远端主播，获取主播的 uid 信息。
        override fun onUserJoined(uid: Int, elapsed: Int) {
            runOnUiThread { // 从 onUserJoined 回调获取 uid 后，调用 setupRemoteVideo，设置远端视频视图。
                setupRemoteVideo(uid)
            }
        }

        //	    加入频道，设置用户身份（主播），（本地）最后和声网服务端交互
        // 加入频道成功后的事件处理
        //加入频道成功
        override fun onJoinChannelSuccess(channel: String?, uid: Int, elapsed: Int) {
            viewModel.startPushStream(i!!)
            super.onJoinChannelSuccess(channel, uid, elapsed)
//            viewModel.startPushStream(uid)
//            viewModel.startPushStreamLiveData.observe(this@DialogActivity, Observer {
//                ToastUtils.showLong(it.message)
//            })
        }
    }

    //直播项目就是一对一直播，就是一个主播对一个粉丝进行语音或者视频聊天，
    //在一对一直播间内，可以实现主播与粉丝之间的语音视频互动，这是目前zui火的直播模式。
    private fun initializeAndJoinChannel(token: String, channelName: String, uid: Int) {
        try {
            val config = RtcEngineConfig()
            config.mContext = baseContext
            config.mAppId = appId
            config.mEventHandler = mRtcEventHandler
            mRtcEngine = RtcEngine.create(config)

            // 视频默认禁用，你需要调用 enableVideo 启用视频流。
            mRtcEngine?.enableVideo()
            // 开启本地视频预览。
            mRtcEngine?.startPreview()
            val container = findViewById<FrameLayout>(R.id.local_video_view_container)
            // 创建一个 SurfaceView 对象，并将其作为 FrameLayout 的子对象。
            val surfaceView = SurfaceView(baseContext)
            container.addView(surfaceView)
            // 将 SurfaceView 对象传入声网，以渲染本地视频。
            mRtcEngine?.setupLocalVideo(
                VideoCanvas(
                    surfaceView,
                    VideoCanvas.RENDER_MODE_FIT,
                    BaseConstant.UID
                )
            )
            val options = ChannelMediaOptions()
            // 根据场景将用户角色设置为 BROADCASTER（开播） 或 AUDIENCE（看播）。

            options.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER
            // 极速直播下的观众，需设置用户级别为 AUDIENCE_LATENCY_LEVEL_LOW_LATENCY。
            //options.audienceLatencyLevel = Constants.AUDIENCE_LATENCY_LEVEL_LOW_LATENCY
            // 直播场景下，设置频道场景为 BROADCASTING。
            options.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING

            // 使用临时 Token 加入频道。
            // 你需要自行指定用户 ID，并确保其在频道内的唯一性。
            mRtcEngine?.joinChannel(token, channelName, BaseConstant.UID, options)
        } catch (e: Exception) {
            throw RuntimeException("Check the error.")
        }

    }

    //2、我们在开播初始化的时候，要把setupLocalVideo这个本地的数据流先
    ////	    开起来，准备好，相当于开启自己的摄像头，把这个本地的画面开起来，
    ////	    参数userid是我们登录的userid
    private fun setupRemoteVideo(uid: Int) {
        val container = binding.remoteVideoViewContainer
        val surfaceView = SurfaceView(baseContext)
        surfaceView.setZOrderMediaOverlay(true)
        container.addView(surfaceView)
        mRtcEngine!!.setupRemoteVideo(VideoCanvas(surfaceView, VideoCanvas.RENDER_MODE_FIT, uid))
    }

    //    主播端连麦：
//
//获取到连麦请求列表，调用服务器接口，服务器返回同意连麦成功
//声网会和本地的SDK交互，回调onUserJoined方法，设置远端视频视图，
//对主播来说，用户就是远端，
    override fun initData() {
        //连麦弹窗
        binding.openLianmai.setOnClickListener {

            var customDialog = CustomDialog_three(this)
            customDialog.show()

            viewModel.zbquerylist(i!!)

            viewModel.LM_QueryLiveData.observe(this, Observer {

                callback(it)
            })
        }

        //弹框认证
        binding.liveRenzheng.setOnClickListener {
            val customDialog = CustomDialog(this)
            customDialog.show()
        }

        binding.openliveImgid.setOnClickListener {
            if (file == null) {
                startActivityForResult(Intent(Intent.ACTION_PICK).setType("image/*"), 1)
            }
        }
        binding.liveKai.setOnClickListener {
            if (file != null) {
                viewModel.getOpenLive(file!!)
                viewModel.mLiveBeanMediatorLiveData.observe(this, Observer {
//                    ToastUtils.showLong(it.message)
                    //Log.i("liveid:", it.liveData.liveId.toString())
                    if ("0000" == it.status) {
                        if (checkSelfPermission(REQUESTED_PERMISSIONS[0], PERMISSION_REQ_ID) &&
                            checkSelfPermission(REQUESTED_PERMISSIONS[1], PERMISSION_REQ_ID)
                        ) {
                        }
                        initializeAndJoinChannel(
                            it.liveData.agoraToken,
                            it.liveData.channelName,
                            BaseConstant.UID
                        )
                        //申请直播推流
                        it?.liveData?.let {
                            i = it.liveId
                        }

                        viewModel.startPushStreamLiveData.observe(this, Observer { sta ->
                            if (sta.status == "0000") {
                                ToastUtils.showLong(it.message)
                            }
                        })
                        connectSocket(it.liveData?.compositeWsUrl!!)
                    } else {
                        ToastUtils.showLong(it.message)
                    }
                })
            } else {
                ToastUtils.showLong("开播错误")
            }
            //隐藏与显示
            ff()
        }
        //关闭直播
        binding.liveClose.setOnClickListener {
            viewModel.closePushStream()
            viewModel.closePushStreamLiveData.observe(this, Observer {
                ToastUtils.showLong(it.message)
            })
        }
    }


    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == 1 && data != null) {
            val data1 = data.data
            file = UriUtils.uri2File(data1)
            val bitmap = ImageUtils.getBitmap(file)
            binding.openliveImgid.setImageBitmap(bitmap)
        }
    }

    private fun connectSocket(compositeWsUrl: String) {
        val webSocketUtils :WebSocketUtils  = WebSocketUtils().startConnect(compositeWsUrl, this)
        webSocketUtils.setOnMessageListener(object : WebSocketUtils.OnMessageListener {
            override fun message(msg: String?) {
                if (msg != null) {
                    Log.d("connectSocket msg", msg.toString())
                    ToastUtils.showLong(msg.toString())
                    val socketBean = GsonUtils.fromJson(msg, SocketBean::class.java)
                    when (socketBean.msgType) {
                        101 -> {}
                        102 -> {}
                        103 -> {}
                        104 -> {}
                    }
                }
            }
        })
    }


    private fun ff() {
        //开播前
        binding.openTextZz.visibility = View.GONE
        binding.openTextLx.visibility = View.GONE
        binding.openliveImgid.visibility = View.GONE
        binding.openView.visibility = View.GONE
        binding.wz.visibility = View.GONE
        binding.openliveFlip.visibility = View.GONE
        binding.openliveMeiyan.visibility = View.GONE
        binding.liveKai.visibility = View.GONE
        binding.liveRenzheng.visibility = View.GONE
        //开播后
        binding.openFirst.visibility = View.VISIBLE
        binding.openTwo.visibility = View.VISIBLE
        binding.openThree.visibility = View.VISIBLE
        binding.openliveNum.visibility = View.VISIBLE
        binding.openHintid.visibility = View.VISIBLE
        binding.openLianmai.visibility = View.VISIBLE
        binding.openQueqiao.visibility = View.VISIBLE
        binding.openShenglue.visibility = View.VISIBLE
        binding.remoteVideoViewContainer.visibility = View.VISIBLE
    }

    override fun getViewBinding() = ActivityDialogBinding.inflate(layoutInflater)

    override fun onDestroy() {
        super.onDestroy()
        mRtcEngine?.stopPreview()
        mRtcEngine?.leaveChannel()
    }
}